//关于子类实例为什么可以赋给父类变量的问题
/*
https://blog.csdn.net/gjj0981/article/details/84187534
1）子类里有一个区域放的父类的实例，子类内存区里有一个this指针，指向了这个内存区里包括的父类实例区，当把引用付给父类时，是把子类内存区里面的父类实例区域的引用给了父类的实例.

2）super相当于指向父类示例的一个指针; 子类只保存子类的信息和super指针; 当JVM加载一个子类的时候也会把它的父类一同加载的，子类内部通过super保存父类的一个引用

也就是说在son类的内存区里，有一个区域放着father类的实例。取名为super；super里保存着指向father类的地址（这也是为什么在子类中可以用super（）来代替父类的原因）。

因此真相大白了，father f=new son();当son类继承了father类之后，它已经保存了指向father类的地址信息，此时即是用父类引用指向子类对象 ，这是一种向上转型，当父类需要使用子类功能时（父类被子类覆盖的方法）就可以将子类对象上转给父类引用。

不仅仅是父类可以指向子类的对象，只要是祖先类都可以指向子类的实例。典型情况，Object是所有类的祖先类，所以Object类型的对象引用可以指向任何对象。例如下面的代码：

Object o = new son();
那么把父类引用指向子类对象的好处是什么呢？
    其实，父类引用指向子类对象就是java的多态。也叫动态绑定。
  把不同的子类对象都当作父类来看，可以屏蔽不同子类对象之间的差异，写出通用的代码，做出通用的编程，以适应需求的不断变化。
  赋值之后，父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。也就是说，父亲的行为像儿子，而不是儿子的行为像父亲
* */
public class Test {
    public static void main(String[] args) {
        Cat cat=new Cat();
        Dog dog=new Dog();
        show(cat);  // 以 Cat 对象调用 show 方法
        show(dog);  // 以 Dog 对象调用 show 方法
        Animal a = new Cat();  // 向上转型
        System.out.println(getType(a)); // 输出：java.lang.Integer
        a.eat();               // 调用的是 Cat 的 eat
        Cat c = (Cat)a;        // 向下转型，强制类型转换
        c.work();        // 调用的是 Cat 的 work
        /*
向下转型后 的变化
关于方法：可以调用子类的所有方法，和属性，类型转为子类
关于属性：调用 的属性为子类 的属性。
向下转型的作用
向上转型时 ，会遗失子类对象独有的其他方法；可以通过向下转型在重新转回。
        * */
  }

  /*
  Object类是Javajava.lang包下的核心类，Object类是所有类的父类，何一个类时候如果没有明确的继承一个父类的话，那么它就是Object的子类；

以下两种类的定义的最终效果是完全相同的：

class Person { }

class Person extends Object { }
————————————————

版权声明：本文为博主原创文章，遵循 CC 4.0 BY-SA 版权协议，转载请附上原文出处链接和本声明。

原文链接：https://blog.csdn.net/weixin_43232955/article/details/89705350
  */
	public static String getType(Object test) {
		return test.getClass().getName().toString();

	}
    public static void show(Animal a)  {
      a.eat();
        // 类型判断
        if (a instanceof Cat)  {  // 猫做的事情
            Cat c = (Cat)a;
            c.work();
        } else if (a instanceof Dog) { // 狗做的事情
            Dog c = (Dog)a;
            c.work();
        }
    }
}


abstract class Animal {
    abstract void eat();
    abstract void work();//为什么work是从来没有被使用过的？而eat却被使用过了？
}

class Cat extends Animal {
    public void eat() {
        System.out.println("吃鱼");
    }
    public void work() {
        System.out.println("抓老鼠");
    }
}

class Dog extends Animal {
    public void eat() {
        System.out.println("吃骨头");
    }
    public void work() {
        System.out.println("看家");
    }
}
